package com.bnz.security.config;

import com.bnz.security.service.MyDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private DataSource dataSource;

//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//         	http.formLogin()        // 使用系统自带的登录表单
//         		.successForwardUrl("/success") //登录成功后跳转到的页面
//         		.and()
//         		.authorizeRequests()           // 除登录相关的其它请求
//         		.anyRequest()
//         		.authenticated();	           // 都要经过认证才能访问
//    }


//    //2. 定制化登录表单
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.formLogin()
//                .loginPage("/login.html")               //指定登录表单页面
//                .loginProcessingUrl("/login")
//                .successForwardUrl("/success")
//                .and()
//                .authorizeRequests()
//                .antMatchers("/login.html","/webjars/**")  //放行/webjars/**
//                .permitAll()                            // 其它需要认证访问
//                .anyRequest()
//                .authenticated()
//                .and()
//                .csrf()         // 禁用csrf功能
//                .disable();
//    }

    //3. 认证和授权
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.exceptionHandling().accessDeniedPage("/unauth.html")
//                .and()
//                .formLogin()
//                .loginPage("/login.html")               //指定登录表单页面
//                .loginProcessingUrl("/login")
//                .successForwardUrl("/success")
//                .and()
//                .authorizeRequests()
//                .antMatchers("/user/findAll")  //放行
//   //             .hasAuthority("user")                     //是否有权限（单个）
//                //.hasAnyAuthority("cc","bb","admin111","aa")   //是否有权限（多个中有一个有）
//                //.hasRole("user")                          //ROLE_角色是否有权限（单个）
//                .hasAnyRole("aa","bb","admin")       //ROLE_角色是否有权限（多个中有一个有）
////                .permitAll()                            // 其它需要认证访问
//
//                .anyRequest()
//                .authenticated()
//                .and()
//                .csrf()         // 禁用csrf功能
//                .disable();
//    }

//   4.通过注解进行认证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling().accessDeniedPage("/unauth.html")
                .and()
                .formLogin()
                .loginPage("/login.html")               //指定登录表单页面
                .loginProcessingUrl("/login")
                .successForwardUrl("/success")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .rememberMe()                          //配置记住我的功能
                .tokenValiditySeconds(100)              //token到期时间，以s为单位
                .tokenRepository(tokenRepos())          //设置记住我功能数据源
                .userDetailsService(userDetailsService)
                .and()
                .csrf()         // 禁用csrf功能
                .disable();
    }

    //5. 设置rememberme的token的数据源
    @Bean
    public PersistentTokenRepository tokenRepos() {

        JdbcTokenRepositoryImpl jdbcTokenRepository=new JdbcTokenRepositoryImpl();
//        jdbcTokenRepository.setCreateTableOnStartup(true);
        jdbcTokenRepository.setDataSource(dataSource);
        return jdbcTokenRepository;
    }

    //设置密码加密器
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
    }

    //7. 指定放行的url路径
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/login.html", "/webjars/**");
    }

    private PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }
}
